/**
 * This file is dedicated to the declarations of the prototypes
 * specific to character information.
 * 
 * @author Levester Chaney
 * @version 0.0.1
 */

// required libraries
#include <vector>

using namespace std;

// constants for binding and initializations
const int MAX_STRING_SIZE = 40;
const int INITIAL_HEALTH_STAT = 200;
const int MAX_SKILL_POINTS = 100;

/////////////////////////////////////////////////////////////////////
//							Abstract classes					   //
/////////////////////////////////////////////////////////////////////

/**
 * A restriction of the types of items that are allowed in the game. Any given
 * item will be of one of these types.
 */
enum itemType
{
	NORMAL,
	ARMOR,
	WEAPON
};

/**
 * A restriction of the social classes that are allowed in the game. Any given
 * player will be of any one of these classes.
 */
enum classType
{
	NOBLE,
	SERVANT,
	PEASANT
};

/**
 * The class to contain and manipulate a location within the 3d game world.
 */
class location
{
private:
	short x, y, z;	// Represents the 3d location within the game world
public:
	/**
	 * Default constructor.
	 */
	location();

	/**
	 * Constructor to generate a new instance of location.
	 * @param x The x coordinate
	 * @param y The y coordinate
	 * @param z The z coordinate
	 */
	location(short x, short y, short z);

	/**
	 * Destructor.
	 */
	~location();

	/**
	 * Retrieves the current x-coordination of the location.
	 */
	short getX() const;

	/**
	 * Retrieves the current x-coordination of the location.
	 */
	short getY() const;

	/**
	 * Retrieves the current x-coordination of the location.
	 */
	short getZ() const;
};

/**
 * The superclass for all skills within the game. The general definition
 * that houses the functionality that is common to all skills.
 */
class ability
{
private:
	char* name;	// The name of the ability (max size allowed will be 40 chars)
	bool trainable;	// Tells whether or not the ability is subject to boost/decay
	int level;	// Represents the level of this skill. To be bounded by MAX_SKILL_POINTS
public:
	/**
	 * Default constructor.
	 */
	ability();

	/**
	 * Constructor to generate a new instance of an ability.
	 * @param name The name of the ability for identification purposes
	 */
	ability(char* name);

	/**
	 * Constructor to generate a new instance of an ability.
	 * @param name The name of the ability for identification purposes
	 * @param trainable Declares whether or not the ability is subject
	 *        to boost and decay
	 */
	ability(char* name, bool trainable);

	/**
	 * Destructor.
	 */
	~ability();

	/**
	 * Retrieves the name of the ability.
	 */
	char* getName() const;

	/**
	 * Tells whether the skill is subject to boost and decay.
	 */
	bool isTrainable() const;

	/**
	 * Retrieves the level of the ability.
	 */
	int getLevel() const;

	/**
	 * Handles the logic that increases the proficiency of an ability.
	 */
	void boost();

	/**
	 * Handles the logic that decreases the proficiency of an ability.
	 */
	void decay();

	/**
	 * Decides the action that this particular ability will take.
	 */
	virtual void action() = 0;
};

/**
 * The superclass for any given item in the game. This is the
 * general definition of the items that can be found and equipped
 * within the game.
 */
class item
{
private:
	char* name;	// The name of the item (max size allowed will be 40 chars)
	itemType type;	// The type of the item i.e. weapon, armor, natural, etc
	bool equippable;	// Is this item allowed to be equipped.
	location* position;	// The current location for the item, null if player has item.
	//buffs declaration
	//texture declaration
	//model declaraction
public:
	/**
	 * Default Constructor.
	 */
	item();

	/**
	 * Constructor to generate a new instance of an item.
	 * @param name The name of the item for identification purposes
	 */
	item(char* name);

	/**
	 * Constructor to generate a new instance of an item.
	 * @param name The name of the item for identification purposes
	 * @param type The type of item i.e. weapon, armor, etc
	 */
	item(char* name, itemType type);

	/**
	 * Constructor to generate a new instance of an item.
	 * @param name The name of the item for identification purposes
	 * @param type The type of item i.e. weapon, armor, etc
	 * @param equippable Tells whether the item can be equipped
	 */
	item(char* name, itemType type, bool equippable);
	
	/**
	 * Deconstructor.
	 */
	~item();

	/**
	 * Retrieves the name of the item.
	 */
	char* getName() const;

	/**
	 * Retrieves the item's type.
	 */
	itemType getItemType() const;

	/**
	 * Tells whether or not the item is equippable.
	 */
	bool isEquippable() const;
	
	/**
	 * Retrieves the current location of the item. If null, a player acquired it.
	 */
	location getLocation() const;

	/**
	 * Sets the location for the item. Mostly used in initialization and when
	 * items are dropped.
	 * @param x The new x coordinate for the item
	 * @param y The new y coordinate for the item
	 * @param z The new z coordinate for the item
	 */
	void setLocation(short x, short y, short z);

	/**
	 * Decides the action that this particular item will take.
	 */
	virtual void action() = 0;
};

/**
 * The class to represent a players inventory. All collected items
 * will be stored within this data type for easier operations and
 * buff control.
 */
class inventory
{
private:
	unsigned long moneyUS;	// The amount of US currency in the player's possession
	vector<item*>* equips;	// The list of items that the player has equipped
	vector<item*>* gathered;	// The list of items that the player has gathered
public:
	/**
	 * Default constructor.
	 */
	inventory();

	/**
	 * Destructor.
	 */
	~inventory();

	/**
	 * Retrieves the amount of money.
	 */
	unsigned long getMoneyUS() const;

	/**
	 * Retrieves the list of equipped items.
	 */
	vector<item*> getEquips() const;

	/**
	 * Retrieves the list of gathered items.
	 */
	vector<item*> getGathered() const;

	/**
	 * Adds a new item into the inventory.
	 * @param i The item to add to the inventory
	 */
	void addItem(item* i);
};

/**
 * The declaration of a given player in the game. This describes
 * the general functionality associated with the player model. That
 * is, player functionality is superclassed here and further
 * implemented in the respective subclasses.
 */
class player
{
private:
	// soft coded instances
	char* name;	// The name of the player, TBD by user at game start (max size allowed will be 40 chars)
	unsigned int hp;	// Health of the player
	classType birthClass;	// The class into which the player is born
	char* birthCity;	// The city which the player is born
	location* position;	// The current location for the player.
	// hard coded instances
	char* birthWorld;	// The world on which the player is born
	signed short virtue;	// Points that determine the good/bad level of the player
	inventory* pack;	// The set of inventory items that the player has
	vector<ability*>* innateSkills;	// The race specific abilities that are not trainable
	vector<ability*>* naturalSkillls;	// The race specific abilities that are trainable
	vector<ability*>* skillset;	// The list of learnable skills that are trainable and not race specific
	//natural weapons
	//weakness
	//resistance
	//immunity
	//buffs declaration
	//texture declaration
	//model declaration
protected:
	/**
	 * Adds an innate ability to the player's arsenal. To be used only be the subclass constructors.
	 * @param a The ability to be added to the player
	 */
	void addInnateAbility(ability* a);

	/**
	 * Adds an natural ability to the player's arsenal. To be used only be the subclass constructors.
	 * @param a The ability to be added to the player
	 */
	void addNaturakAbility(ability* a);

	/**
	 * Sets the birth world for the player.
	 * @param world The world in which the player is born
	 */
	void setBirthWorld(char* world);
public:
	/**
	 * Default constructor.
	 */
	player();

	/**
	 * Constructor to generate a new instance of player.
	 * @param name The name of the player
	 */
	player(char* name);

	/**
	 * Constructor to generate a new instance of player.
	 * @param name The name of the player
	 * @param birthClass The class of the player
	 */
	player(char* name, classType birthClass);
	
	/**
	 * Constructor to generate a new instance of player.
	 * @param name The name of the player
	 * @param birthClass The class in which the player is born
	 * @param birthCity The city where the player is born
	 */
	player(char* name, classType birthClass, char* birthCity);
	
	/**
	 * Destructor.
	 */
	~player();

	/**
	 * Retrieves the name of the player.
	 */
	char* getName() const;

	/**
	 * Retrieves the good/evil level for the player.
	 */
	signed short getVirtue() const;

	/**
	 * Retrieves the birth world of the player.
	 */
	char* getBirthWorld() const;

	/**
	 * Retrieves the birth city for the player.
	 */
	char* getBirthCity() const;

	/**
	 * Retrieves the social status of the player.
	 */
	classType getBirthClass() const;

	/**
	 * Retrieves the player's inventory.
	 */
	inventory* getInventory() const;

	/**
	 * Retrieves the health of the player.
	 */
	unsigned int getHp() const;

	/**
	 * Retrieves the array of innate skills.
	 */
	vector<ability*> getInnateSkills() const;
	
	/**
	 * Retrieves the array of natural skills.
	 */
	vector<ability*> getNaturalSkillls() const;
	
	/**
	 * Retrieves the array of regular skills.
	 */
	vector<ability*> getSkillset() const;

	/**
	 * Retrieves the current location of the item.
	 */
	location getLocation() const;

	/**
	 * Adds an item into the inventory.
	 * @param i The item to be added into the inventory
	 */
	void addItem(item* i);

	/**
	 * Adds an innate ability to the player's arsenal.
	 * @param a The ability to be added to the player
	 */
	void addAbility(ability* a);

	/**
	 * Sets the location for the item. Mostly used in initialization and when
	 * items are dropped.
	 * @param x The new x coordinate for the item
	 * @param y The new y coordinate for the item
	 * @param z The new z coordinate for the item
	 */
	void setLocation(short x, short y, short z);
	
	/**
	 * Alters the virtue level of the player.
	 * @param amount The amount by which to boost/decay the virtue
	 */
	void setVirtue(signed short amount);

	/**
	 * Alters the health level of the player.
	 * @param amount The amount by which to damage/increase the health
	 */
	void setHealth(unsigned int amount);

	/**
	 * Prototypes a function for the action a player may choose to
	 * do. This function may disappear it is really just for me to
	 * test the properties of Visual Studio.
	 */
	virtual void action() = 0;
};